// **************************************************************
// Com ++ Framework by the C++ World
// Please report defects: mailto:compp@cplusplusworld.com
// Please visit: http://www.cplusplusworld.com/socketlibrary.html
// **************************************************************


#include "SysPlusPlus/syscall.h"
#include "ComPlusPlus/Daemon.h"

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>


/**
 * Blocks the following signals:
 * SIGPIPE
 * SIGHUP
 * SIGCLD
 * SIGCHLD
 * SIGURG
 * Should always be applied. 
 */
void syspp::Daemon::Daemonize_light() {
#ifdef SIGPIPE
    signal ( SIGPIPE, SIG_IGN);
#endif
#ifdef SIGHUP
    signal ( SIGHUP,  SIG_IGN);
#endif
#ifdef SIGCLD
    signal ( SIGCLD,  SIG_IGN);
#endif
#ifdef SIGCHLD
    signal ( SIGCHLD,  SIG_IGN);
#endif
#ifdef SIGURG
    signal ( SIGURG,  SIG_IGN);
#endif

}

/**
 * Runtime setting:
 * - Changes to "/" directory
 * - Forks off and lets the parent die
 * Ignores the following Signals
	SIGINT
	SIGQUIT
	SIGILL 	 Illegal instruction (ANSI).  
	SIGTRAP	 Trace trap (POSIX).  
	SIGABRT	 Abort (ANSI).  
	SIGIOT	 IOT trap (4.2 BSD).  
	SIGBUS	 BUS error (4.2 BSD).  
	SIGFPE	 Floating-point exception (ANSI).  
	SIGUSR1	 User-defined signal 1 (POSIX).  
	SIGUSR2	 User-defined signal 2 (POSIX).  
	SIGALRM	 Alarm clock (POSIX).  
	SIGSTKFLT	 Stack fault.  
	SIGTSTP	 Keyboard stop (POSIX).  
	SIGTTIN	 Background read from tty (POSIX).  
	SIGTTOU	 Background write to tty (POSIX).  
	SIGXCPU	 CPU limit exceeded (4.2 BSD).  
	SIGXFSZ	 File size limit exceeded (4.2 BSD).  
	SIGVTALRM	 Virtual alarm clock (4.2 BSD).  
	SIGPROF	 Profiling alarm clock (4.2 BSD).  
	SIGWINCH	 Window size change (4.3 BSD, Sun).  
	SIGPOLL	 Pollable event occurred (System V).  
	SIGIO	 I/O now possible (4.2 BSD).  
	SIGPWR	 Power failure restart (System V).  
	SIGSYS	 Bad system call.  
 * 
 *  
 */
void syspp::Daemon::Daemonize_full() {

    syspp::Call::Chdir ( "/" );


#ifdef SIGINT
    signal ( SIGINT, SIG_IGN);
#endif
#ifdef SIGQUIT
    signal ( SIGQUIT, SIG_IGN);
#endif
#ifdef SIGILL
    signal ( SIGILL, SIG_IGN); 	/* Illegal instruction (ANSI).  */
#endif
#ifdef SIGTRAP
    signal ( SIGTRAP, SIG_IGN);	/* Trace trap (POSIX).  */
#endif
#ifdef SIGABRT
    signal ( SIGABRT, SIG_IGN);	/* Abort (ANSI).  */
#endif
#ifdef SIGIOT
    signal ( SIGIOT, SIG_IGN);	/* IOT trap (4.2 BSD).  */
#endif
#ifdef SIGBUS
    signal ( SIGBUS, SIG_IGN);	/* BUS error (4.2 BSD).  */
#endif
#ifdef SIGFPE
    signal ( SIGFPE, SIG_IGN);	/* Floating-point exception (ANSI).  */
#endif
#ifdef SIGUSR1
    signal ( SIGUSR1, SIG_IGN);	/* User-defined signal 1 (POSIX).  */
#endif
#ifdef SIGUSR2
    signal ( SIGUSR2, SIG_IGN);	/* User-defined signal 2 (POSIX).  */
#endif
#ifdef SIGALRM
    signal ( SIGALRM, SIG_IGN);	/* Alarm clock (POSIX).  */
#endif
#ifdef SIGSTKFLT
    signal ( SIGSTKFLT, SIG_IGN);	/* Stack fault.  */
#endif
#ifdef SIGTSTP
    signal ( SIGTSTP, SIG_IGN);	/* Keyboard stop (POSIX).  */
#endif
#ifdef SIGTTIN
    signal ( SIGTTIN, SIG_IGN);	/* Background read from tty (POSIX).  */
#endif
#ifdef SIGTTOU
    signal ( SIGTTOU, SIG_IGN);	/* Background write to tty (POSIX).  */
#endif
#ifdef SIGXCPU
    signal ( SIGXCPU, SIG_IGN);	/* CPU limit exceeded (4.2 BSD).  */
#endif
#ifdef SIGXFSZ
    signal ( SIGXFSZ, SIG_IGN);	/* File size limit exceeded (4.2 BSD).  */
#endif
#ifdef SIGVTALRM
    signal ( SIGVTALRM, SIG_IGN);	/* Virtual alarm clock (4.2 BSD).  */
#endif
#ifdef SIGPROF
    signal ( SIGPROF, SIG_IGN);	/* Profiling alarm clock (4.2 BSD).  */
#endif
#ifdef SIGWINCH
    signal ( SIGWINCH, SIG_IGN);	/* Window size change (4.3 BSD, Sun).  */
#endif
#ifdef SIGPOLL
    signal ( SIGPOLL, SIG_IGN);	/* Pollable event occurred (System V).  */
#endif
#ifdef SIGIO
    signal ( SIGIO, SIG_IGN);	/* I/O now possible (4.2 BSD).  */
#endif
#ifdef SIGPWR
    signal ( SIGPWR, SIG_IGN);	/* Power failure restart (System V).  */
#endif
#ifdef SIGSYS
    signal ( SIGSYS, SIG_IGN);	/* Bad system call.  */
#endif
 

    switch ( syspp::Call::Fork () ) {
	case -1: {
	    break;
	} 
	case 0: {
	    break;
	}
	default: {
	    exit(0);
	}
    }

}

syspp::Daemon::Daemon() {
    syspp::Daemon::Daemonize_full();
}

syspp::Daemon::~Daemon() {
}
